home *** CD-ROM | disk | FTP | other *** search
-
- /*
- File: ConicLibrary.c
-
- Contains: graphics libraries - conic library
-
- Written by: Mike Reed
-
- Copyright: © 1995 by Apple Computer, Inc., all rights reserved.
-
- Change History (most recent first):
-
- <1> 1/9/95 JD First checked in.
- */
-
- #include "GraphicsLibraries.h"
-
- /*
- * kNumPoints must be at least 2^n + 2 where n is kMaxRecursion.
- * Current static implementation limits ctr bits to 1 long so
- * kMaxRecursion cannot be greater than 4
- */
- #define kMaxRecursion 4
-
- #define kNumPoints ((1L << kMaxRecursion) + 2)
-
- #define kNumOfStaticLongs (2 + kNumPoints*2)
-
- /*
- * This dude just does what it says. I broke up some of the formulas
- * to try and reduce overflow of intermediate results. This is a good
- * place to optimize with assembler for speed and accuracy.
- */
- static void SubdivideConic(register const conic *c, conic *left, conic *rite)
- {
- register Fixed lambda = c->lambda;
- register Fixed lambdaPlusOne = lambda + fixed1;
- register Fixed lambdaBx = FixedMultiply(lambda, c->b.x);
- register Fixed lambdaBy = FixedMultiply(lambda, c->b.y);
-
- left->a = c->a;
- left->b.x = FixedDivide(c->a.x + lambdaBx, lambdaPlusOne);
- left->b.y = FixedDivide(c->a.y + lambdaBy, lambdaPlusOne);
-
- left->c.x = FixedDivide((c->a.x + c->c.x >> 1) + lambdaBx, lambdaPlusOne);
- left->c.y = FixedDivide((c->a.y + c->c.y >> 1) + lambdaBy, lambdaPlusOne);
- rite->a = left->c;
-
- rite->b.x = FixedDivide(c->c.x + lambdaBx, lambdaPlusOne);
- rite->b.y = FixedDivide(c->c.y + lambdaBy, lambdaPlusOne);
- rite->c = c->c;
-
- left->lambda = rite->lambda = FixedSquareRoot(lambdaPlusOne >> 1);
- }
- /*
- * This guy fills out ptPtr with ON/OFF-gxCurve points. recursion is the maximum
- * depth I can call myself, since storage for ptPtr is pre-allocated.
- */
- static gxPoint* Conic2Path(const conic *aConic, gxPoint *ptPtr, short recursion)
- {
- if ((recursion-- > 0))
- {
- conic leftConic, riteConic;
- SubdivideConic(aConic, &leftConic, &riteConic);
- ptPtr = Conic2Path(&leftConic, ptPtr, recursion);
- ptPtr = Conic2Path(&riteConic, ptPtr, recursion);
- }
- else
- {
- *ptPtr++ = aConic->b;
- }
- return ptPtr;
- }
-
- /*
- * The lambda for a parabola is 1. Error should be
- * (a - 2b + c) (lambda - 1)
- * -----------------------
- * 8
- */
- static short RecursionDepth(register const conic *aConic, register Fixed tolerance)
- {
- register Fixed dx, dy;
-
- {
- register Fixed tmp = aConic->lambda - fixed1 + 4 >> 3;
- dx = aConic->b.x;
- dx = FixedMultiply( aConic->a.x - dx - dx + aConic->c.x, tmp );
- dy = aConic->b.y;
- dy = FixedMultiply( aConic->a.y - dy - dy + aConic->c.y, tmp );
- }
- {
- register short count;
- register Fixed length = Magnitude( dx, dy );
- for (count = 0; length > tolerance; count++)
- length >>= 4;
- return count;
- }
- }
-
- /*
- * Given a conic geometry, returns a gxPath
- */
- static void ConicPath(long *storage, const conic *aConic)
- {
- Fixed tolerance = GXGetShapeCurveError( GXGetDefaultShape(gxPathType) );
- gxPoint* ptPtr;
- long* longp = storage;
- short count;
-
- count = RecursionDepth(aConic, tolerance);
- if (count > kMaxRecursion)
- count = kMaxRecursion;
-
- ptPtr = (gxPoint*)&storage[2];
- *ptPtr++ = aConic->a;
- ptPtr = Conic2Path(aConic, ptPtr, count);
- *ptPtr++ = aConic->c;
-
- count = ptPtr - (gxPoint*)&storage[2];
- storage[0] = count;
- storage[1] = 0x7FFFFFFF ^ ( 1L << 32 - count );
- }
-
- /***********************************************************************/
-
- void DrawConic(const conic *aConic, gxShapeFill aFill)
- {
- gxShape s = NewConic(aConic);
- if (aFill)
- GXSetShapeFill(s, aFill);
- GXSetShapeAttributes(s, GXGetShapeAttributes(s) & ~gxCachedShape);
- GXDrawShape(s);
- GXDisposeShape(s);
- }
-
- gxShape NewConic(const conic *aConic)
- {
- long storage[kNumOfStaticLongs];
-
- ConicPath(storage, aConic);
- return NewPath((gxPath*)storage);
- }
-
- void SetConic(gxShape dest, const conic *aConic)
- {
- long storage[kNumOfStaticLongs];
-
- ConicPath(storage, aConic);
- SetPath(dest, 0, (gxPath*)storage);
- }
-